#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QByteArray>
#include <openssl/rand.h>

extern "C" {
	    #include "../common/crypto_utils.c"
}

MainWindow::MainWindow(QWidget *parent)
	    : QMainWindow(parent)
	          , ui(new Ui::MainWindow)
{
	    ui->setupUi(this);
	        
	        socket = new QTcpSocket(this);
		    connect(socket, &QTcpSocket::readyRead, this, &MainWindow::readSocket);
		        connect(socket, &QTcpSocket::disconnected, this, &MainWindow::disconnected);
			    
			    ui->chatGroup->setEnabled(false);
}

MainWindow::~MainWindow()
{
	    delete ui;
}

void MainWindow::on_loginButton_clicked()
{
	    QString username = ui->usernameEdit->text();
	        QString password = ui->passwordEdit->text();
		    
		    if (username.isEmpty() || password.isEmpty()) {
			            QMessageBox::warning(this, "Error", "Username and password cannot be empty");
				            return;
					        }
		        
		        socket->connectToHost("127.0.0.1", SERVER_PORT);
			    if (!socket->waitForConnected(3000)) {
				            QMessageBox::warning(this, "Error", "Could not connect to server");
					            return;
						        }
			        
			        sendLoginRequest(username, password);
}

void MainWindow::sendLoginRequest(const QString &username, const QString &password)
{
	    generate_salt(salt, sizeof(salt));
	        
	        unsigned char password_hash[SM3_DIGEST_LENGTH];
		    compute_sm3_hash(password.toStdString().c_str(), salt, password_hash);
		        
		        LoginRequest login_req;
			    strncpy(login_req.username, username.toStdString().c_str(), MAX_USERNAME_LEN);
			        memcpy(login_req.password_hash, password_hash, SM3_DIGEST_LENGTH);
				    
				    MessageHeader header = {MSG_TYPE_LOGIN, sizeof(LoginRequest)};
				        socket->write((const char *)&header, sizeof(header));
					    socket->write((const char *)&login_req, sizeof(login_req));
}

void MainWindow::readSocket()
{
	    while (socket->bytesAvailable() >= sizeof(MessageHeader)) {
		            MessageHeader header;
			            socket->peek((char *)&header, sizeof(header));
				            
				            if (socket->bytesAvailable() < sizeof(header) + header.msg_len) {
						                return; // 等待完整消息
								        }
					            
					            socket->read((char *)&header, sizeof(header));
						            QByteArray data = socket->read(header.msg_len);
							            
							            switch (header.msg_type) {
									                case MSG_TYPE_LOGIN_RESP: {
															                  LoginResponse *resp = (LoginResponse *)data.data();
																	                  if (resp->success) {
																				                      username = ui->usernameEdit->text();
																						                          ui->loginGroup->setEnabled(false);
																									                      ui->chatGroup->setEnabled(true);
																											                          showMessage("Login successful");
																														                      
																														                      RAND_bytes(session_key, sizeof(session_key));
																																                      } else {
																																			                          QMessageBox::warning(this, "Error", "Login failed");
																																						                      socket->disconnectFromHost();
																																								                      }
																			                  break;
																					              }
														              case MSG_TYPE_CHAT: {
																			                  ChatMessage *chat_msg = (ChatMessage *)data.data();
																					                  unsigned char decrypted_msg[MAX_MSG_LEN];
																							                  
																							                  sm4_decrypt(session_key, chat_msg->encrypted_msg, 
																											                             decrypted_msg, chat_msg->msg_len);
																									                  
																									                  QString message = QString::fromUtf8((const char *)decrypted_msg, chat_msg->msg_len);
																											                  showMessage(QString("%1: %2").arg(chat_msg->target_user).arg(message));
																													                  break;
																															              }
																		              default:
																		                  showMessage("Unknown message type received");
																				                  break;
																						          }
								        }
}

void MainWindow::on_sendButton_clicked()
{
	    QString message = ui->messageEdit->text();
	        if (message.isEmpty()) return;
		    
		    sendChatMessage(message);
		        ui->messageEdit->clear();
}

void MainWindow::sendChatMessage(const QString &message)
{
	    ChatMessage chat_msg;
	        strncpy(chat_msg.target_user, "user2", MAX_USERNAME_LEN); // 简化版，固定发送给user2
		    
		    QByteArray plaintext = message.toUtf8();
		        sm4_encrypt(session_key, (const unsigned char *)plaintext.constData(), 
					               chat_msg.encrypted_msg, plaintext.size());
			    chat_msg.msg_len = plaintext.size();
			        
			        MessageHeader header = {MSG_TYPE_CHAT, sizeof(ChatMessage)};
				    socket->write((const char *)&header, sizeof(header));
				        socket->write((const char *)&chat_msg, sizeof(chat_msg));
					    
					    showMessage(QString("You: %1").arg(message));
}

void MainWindow::showMessage(const QString &message)
{
	    ui->chatArea->append(message);
}

void MainWindow::disconnected()
{
	    ui->loginGroup->setEnabled(true);
	        ui->chatGroup->setEnabled(false);
		    showMessage("Disconnected from server");
}
